
#include<winsock2.h>
#include<stdio.h>

#include"constants.h"
#include"play.h"
#include"record.h"
#include"thread_lib.h"


// =====Definitions =========
typedef enum {false = 0, true = 1} bool;

// =====Global Variables ====
DWORD g_server_text_threadId;
DWORD g_server_voice_play_threadId;
DWORD g_server_voice_record_threadId;


// =====Functions============
DWORD WINAPI server_text_thread(LPVOID   lpParam)   
{   
	SOCKET sock=(SOCKET)lpParam;   
	char szBuff[DEFAULT_BUFFER];   
	int ret;
	
	while(1)   
	{   
		ret = recv(sock, szBuff, DEFAULT_BUFFER, 0);   
		if   (ret   ==   0) 
		{
			break;
		}
		else  if(ret == SOCKET_ERROR)   
		{   
			printf("recv()  failed:  %d\n",   WSAGetLastError()); 
			closesocket(sock);  
			break;   
		}   
 
	//	printf("received bytes=%d\n", ret);
		szBuff[ret]   =   '\0'; 
		printf("Client Says: %s\n", szBuff);  
	}   
	
	return   0;   
} 


	
	

DWORD WINAPI server_input_thread(LPVOID   lpParam)   
{   
	SOCKET sock=(SOCKET)lpParam;   
	char szBuff[DEFAULT_BUFFER]={0};   
	int ret;   
	
	while(1)
	{
		if(gets(szBuff))
		{
			ret = send(sock, szBuff, strlen(szBuff), 0);   
			if(ret == 0)   
			{
				continue;   
			}
			else if(ret == SOCKET_ERROR)   
			{   
				printf("send() failed:   %d\n",   WSAGetLastError());   
				continue;   
			}   
			//printf("Send   %d   bytes\n",   ret);   
			memset(szBuff, 0, DEFAULT_BUFFER);
		}
	}
	
	return   0;   
} 

SOCKET startSocketListening(void)
{
	WSADATA wsd; 
	SOCKET sListen;
	struct   sockaddr_in local;

	if(WSAStartup(MAKEWORD(2,2), &wsd) != 0)   
	{   
		printf("Failed to load Winsock!\n");   
		return INVALID_SOCKET;  
	}  

	sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);   
	if(sListen == SOCKET_ERROR)   
	{   
		printf("socket() failed:   %d\n",   WSAGetLastError());   
		WSACleanup();  
		return INVALID_SOCKET;
	}   
	local.sin_addr.s_addr = htonl(INADDR_ANY);   
	local.sin_family = AF_INET;   
	local.sin_port = htons(DEFAULT_PORT);   
	
	if(bind(sListen, (struct sockaddr*)&local, sizeof(local)) == SOCKET_ERROR)   
	{   
		printf("bind() failed: %d\n", WSAGetLastError());   
		closesocket(sListen); 
		WSACleanup(); 
		return INVALID_SOCKET;
	}   

	listen(sListen, MAX_SIMU_CONNECT_REQ); 
	
	return sListen;
}


SOCKET server_accept_client(SOCKET sListen, struct sockaddr_in* p_client, int* p_iAddrSize)
{
	SOCKET sClient = INVALID_SOCKET;

	sClient = accept(sListen, (struct sockaddr*)p_client,  p_iAddrSize);                   
	if   (sClient ==  INVALID_SOCKET)   
	{                   
		printf("accept()   failed:   %d\n",   WSAGetLastError());   
		return INVALID_SOCKET;   
	}   

	printf("Accepted client: %s:%d\n", inet_ntoa(p_client->sin_addr), ntohs(p_client->sin_port));
	return sClient;
}


void server_startup(void)
{
	SOCKET sListen, sClient = INVALID_SOCKET, sClientVoice = INVALID_SOCKET;
	bool sClientConnected = false;
	struct sockaddr_in client;
	int iAddrSize;
	DWORD dwThreadId;

	sListen = startSocketListening();

	iAddrSize = sizeof(client);   
	while(1)   
	{   
		if(!sClientConnected)
		{
			sClient = server_accept_client(sListen, &client, &iAddrSize);
			if( sClient != INVALID_SOCKET)
			{
				sClientConnected = true;  
				create_thread(server_text_thread, sClient, &g_server_text_threadId);
				create_thread(server_input_thread, sClient, &dwThreadId);
			}
		}
		else
		{
			sClientVoice = server_accept_client(sListen, &client, &iAddrSize); 
			if( sClient != INVALID_SOCKET)
			{
				create_thread(voice_play_thread_runner, sClientVoice, &g_server_voice_play_threadId);  
				create_thread(voice_record_thread_runner, sClientVoice, &g_server_voice_record_threadId);
				

			}
		}
  
	}   

	closesocket(sListen);    
	WSACleanup();     
}





















